home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-14 | 13.6 KB | 533 lines | [TEXT/CWIE] |
- // --------------------------------------------------------------------------------
- // CPowerPlantAdaptor.cp
- // (c) 1996 Microsoft Corporation. All Rights Reserved.
- //
- // This class is based on a smaller example from ocPPPict included in the ActiveX
- // DR1 examples.
- //
- // The process here is very simple: events are routed through LGrafPortView in
- // PowerPlant. There are some current "issues" that are being worked on:
- //
- // o This class should do more and you should derive from it. Minimal effort
- // has gone into making this class very useful.
- // o I had to create a separate scroller class (CFixedScroller) because the
- // regular PowerPlant one does Bad Things when included in an LGrafPort view.
- // Read the notes in CFixedScroller for more on this.
- //
- // o You can't have more than one on a single page yet, unfortunately.
- // --------------------------------------------------------------------------------
-
- #include "ocheaders.h"
-
- #include "CPPActiveX.h"
- #include "CCFragResource.h"
- #include "CTestView.h"
-
- #include <UDrawingState.h>
- #include <UEnvironment.h>
- #include <URegistrar.h>
- #include <UReanimator.h>
- #include <LPeriodical.h>
-
- static QDGlobalsPtr GetQDGlobals(void);
-
- const ResIDT DEFAULT_VIEW = 1001;
- const Uint32 DefaultIdleRefCon = 0;
-
- extern void InitPowerPlantControl();
-
- // --------------------------------------------------------------------------------
- // PowerPlant requires that if we're going to use LGrafPortView, we have
- // to setup some static variables first. You can read all about this in
- // LGrafPortView.cp (double-click the word and hit command-D).
- // --------------------------------------------------------------------------------
-
- void
- CPPActiveX::InitModule()
- {
- UQDGlobals::SetQDGlobals( GetQDGlobals() );
- Int32 qdVersion = gestaltOriginalQD;
- Gestalt(gestaltQuickdrawVersion, &qdVersion);
- UEnvironment::SetFeature(env_SupportsColor, (qdVersion > gestaltOriginalQD));
-
- // Register our baseline objects. This is bare miniumum stuff
-
- URegistrar::RegisterClass(LGrafPortView::class_ID, (ClassCreatorFunc) LGrafPortView::CreateGrafPortViewStream);
- URegistrar::RegisterClass(LPane::class_ID, (ClassCreatorFunc) LPane::CreatePaneStream);
- URegistrar::RegisterClass(LView::class_ID, (ClassCreatorFunc) LView::CreateViewStream);
-
- InitPowerPlantControl();
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- CPPActiveX::CPPActiveX(void)
- : CBaseControl(),
- LGrafPortView()
- {
- InitModule();
-
- mMainView = nil;
- mOwnedFoci = EmptyFocusSet;
- }
-
-
- // --------------------------------------------------------------------------------
- // Destructor. Rather boring here.
- // --------------------------------------------------------------------------------
-
- CPPActiveX::~CPPActiveX()
- {
- if (mMainView)
- delete mMainView;
- }
-
-
- // --------------------------------------------------------------------------------
- // SetSite
- //
- // Tell our site we want idle time.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::SetSite(
- IUnknown* inUnkSite)
- {
- ErrorCode theResult = E_FAIL;
-
- if (inUnkSite)
- {
- if (mContainerSiteP)
- {
- mContainerSiteP->SetIdleTime(RemoveAllIdlers, DefaultIdleRefCon);
- }
-
- theResult = CBaseControl::SetSite(inUnkSite);
-
- if (theResult == S_OK && mContainerSiteP)
- {
- mContainerSiteP->SetIdleTime(::GetCaretTime(), DefaultIdleRefCon);
- }
- }
-
- return theResult;
- }
-
-
- // --------------------------------------------------------------------------------
- // Draw
- //
- // Very simple. We have to adjust our size if need be (this was set to true in
- // the constructor of this class). We also place ourselves in the view and then
- // tell the grafport to do its business.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::Draw(
- DrawContext *inContext)
- {
- if (inContext->DrawAspect != DVASPECT_CONTENT)
- return ResultFromScode(DV_E_DVASPECT);
-
- StColorPortState savePortState(inContext->Port);
-
- CCFragResource ResourceSetter;
-
- RealignSelf(inContext);
-
- FocusDraw();
- LGrafPortView::Draw(nil);
- OutOfFocus(nil);
-
- return S_OK;
- }
-
- void
- CPPActiveX::DrawSelf() // poor man's debug thing. :-)
- {
- if (mMainView == nil)
- {
- ::MoveTo(10, 10);
- ::DrawString("\pPP View is empty.");
- }
- }
-
- // --------------------------------------------------------------------------------
- // NewContext
- //
- // create a new context info structure
- // --------------------------------------------------------------------------------
-
- CBaseContextInfo*
- CPPActiveX::NewContext(Uint32 inContextID)
- {
- CPPContextInfo* NewContextInfo = new CPPContextInfo(this, inContextID);
-
- if (!mMainView)
- {
- DrawContext Context = {BeginPortType};
- if (mContainerSiteP->AcquireContext(inContextID, &Context) == S_OK)
- {
- mMainView = CreateMainView();
- if (mMainView)
- mMainView->PutInside(this);
-
- mContainerSiteP->ReleaseContext(&Context);
- }
- }
-
- return NewContextInfo;
- }
-
-
- // --------------------------------------------------------------------------------
- // SetFocus
- //
- // Acquire or release a set of focus types.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::SetFocus(FocusCommand inCommand, FocusSet inFocus)
- {
- ErrorCode theResult = S_OK;
- StColorPortState savePort(UQDGlobals::GetCurrentPort());
-
- switch (inCommand)
- {
- case TakeNextCommand:
- case TakePrevCommand:
- if (mOwnedFoci)
- // a TakeNext or a TakePrev on a control which doesn't embed and
- // has the focus should fail
- theResult = E_FAIL;
- else
- {
- // if the container is offering us the one focus we want, take all of them
- if (inFocus & KeyboardFocus)
- {
- mOwnedFoci = FocusSet(mOwnedFoci | inFocus);
- LCommander* theSub = GetLatentSub();
- if (theSub)
- SwitchTarget(theSub);
- }
- else
- // otherwise, say no thanks
- theResult = E_FAIL;
- }
- break;
- case RequestReleaseCommand:
- case ReleaseCommand:
- mOwnedFoci = FocusSet(mOwnedFoci & ~inFocus); // really easy for us
- if ((inFocus & KeyboardFocus) && IsOnDuty())
- {
- SwitchTarget(nil);
- }
- break;
- }
-
- return theResult;
- }
-
-
- // --------------------------------------------------------------------------------
- // DoMouse
- //
- // Handle a mouse event.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::DoMouse(
- MouseEventType inMouseET,
- PlatformEvent* inEvent)
- {
- CCFragResource ResourceSetter;
- DrawContext Context = {BeginPortType};
-
- if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
- {
- RealignSelf(&Context);
-
- switch (inMouseET)
- {
- case MouseDown:
- case MouseUp:
- ClickInContent(*inEvent);
- break;
- }
-
- mContainerSiteP->ReleaseContext(&Context);
- }
-
- return S_OK;
- }
-
- // --------------------------------------------------------------------------------
- // DoKey
- //
- // Handle a key event.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::DoKey(
- KeyEventType inKeyET,
- Char8 inChar,
- PlatformEvent* inEvent)
- {
- #pragma unused (inChar)
- CCFragResource ResourceSetter;
- DrawContext Context = {BeginPortType};
-
- if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
- {
- RealignSelf(&Context);
-
- switch (inKeyET)
- {
- case KeyDown:
- case AutoKey:
- {
- LCommander *target = LCommander::GetTarget();
- if (target != nil)
- target->ProcessKeyPress(*inEvent);
- break;
- }
- }
-
- mContainerSiteP->ReleaseContext(&Context);
- }
-
- return S_OK;
- }
-
- // --------------------------------------------------------------------------------
- // DoIdle
- //
- // Perform idle time tasks.
- // --------------------------------------------------------------------------------
-
- STDMETHODIMP
- CPPActiveX::DoIdle(
- Uint32 IdleRefCon)
- {
- #pragma unused (IdleRefCon)
- CCFragResource ResourceSetter;
- DrawContext Context = {BeginPortType};
- EventRecord theEvent;
-
- if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
- {
- theEvent.what = nullEvent;
- theEvent.message = 0L;
- theEvent.when = ::TickCount();
- theEvent.where.h = theEvent.where.v = 0;
- theEvent.modifiers = 0;
-
- RealignSelf(&Context);
-
- FocusDraw();
- LPeriodical::DevoteTimeToIdlers(theEvent);
- OutOfFocus(nil);
-
- mContainerSiteP->ReleaseContext(&Context);
- }
-
- return S_OK;
- }
-
- // --------------------------------------------------------------------------------
- // PutOnDuty
- //
- // This commander is going on duty (LCommander).
- // --------------------------------------------------------------------------------
-
- void
- CPPActiveX::PutOnDuty()
- {
- if (!(mOwnedFoci & KeyboardFocus))
- {
- if (mContainerSiteP->RequestFocus(true, KeyboardFocus) == S_OK)
- mOwnedFoci = FocusSet(mOwnedFoci | KeyboardFocus);
- }
- }
-
-
- // --------------------------------------------------------------------------------
- // TakeOffDuty
- //
- // This commander is going off duty (LCommander).
- // --------------------------------------------------------------------------------
-
- void
- CPPActiveX::TakeOffDuty()
- {
- if (mOwnedFoci & KeyboardFocus)
- {
- if (mContainerSiteP->RequestFocus(false, KeyboardFocus) == S_OK)
- mOwnedFoci = FocusSet(mOwnedFoci & ~KeyboardFocus);
- }
- }
-
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- void
- CPPActiveX::RealignSelf(
- DrawContext *inContext)
- {
- RgnHandle clip = inContext->Port->clipRgn;
-
- Rect r = inContext->Location;
-
- ::OffsetRect(&r, -(inContext->Port->portRect.left), -(inContext->Port->portRect.top));
-
- PlaceInSuperFrameAt(r.left, r.top, false);
- ResizeFrameTo( r.right - r.left, r.bottom - r.top, false);
-
- if (clip != nil)
- {
- mRevealedRect = (**clip).rgnBBox;
- ::OffsetRect(&mRevealedRect, -(inContext->Port->portRect.left), -(inContext->Port->portRect.top));
- }
-
- if (mMainView != nil) mMainView->AdaptToNewSurroundings();
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- LView*
- CPPActiveX::CreateMainView()
- {
- CCFragResource resSaver;
-
- CTestView *theView = (CTestView*) UReanimator::ReadObjects('PPob', DEFAULT_VIEW);
- if (theView)
- {
- theView->FinishCreate();
- }
-
- return ((LView *) theView);
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- CPPContextInfo::CPPContextInfo(CPPActiveX* inControlP, Uint32 ContextID) : CBaseContextInfo(inControlP, ContextID)
- {
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- CPPContextInfo::~CPPContextInfo(void)
- {
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- ErrorCode
- CPPContextInfo::Activate(Boolean8 Acquired)
- {
- #pragma unused (Acquired)
-
- if (((CPPActiveX*)mControlP)->mMainView)
- ((CPPActiveX*)mControlP)->Activate();
-
- return S_OK;
- }
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- ErrorCode
- CPPContextInfo::Deactivate(Boolean8 Acquired)
- {
- #pragma unused (Acquired)
-
- if (((CPPActiveX*)mControlP)->mMainView)
- ((CPPActiveX*)mControlP)->Deactivate();
-
- return S_OK;
- }
-
-
- // --------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------
-
- QDGlobalsPtr GetQDGlobals(void)
- {
- ProcessSerialNumber PSN;
- FSSpec myFSSpec;
- Str63 name;
- ProcessInfoRec infoRec;
- OSErr Result = noErr;
- CFragConnectionID connID;
- Str255 errName;
- QDGlobalsPtr QDGlobals = NULL;
- //
- // Ask the system if CFM is available.
- //
- long response;
- OSErr err = ::Gestalt(gestaltCFMAttr, &response);
- Boolean hasCFM = ::BitTst(&response, 31-gestaltCFMPresent);
-
- if (hasCFM)
- {
- //
- // GetProcessInformation takes a process serial number and
- // will give us back the name and FSSpec of the application.
- // See the Process Manager in IM.
- //
- infoRec.processInfoLength = sizeof(ProcessInfoRec);
- infoRec.processName = name;
- infoRec.processAppSpec = &myFSSpec;
-
- PSN.highLongOfPSN = 0;
- PSN.lowLongOfPSN = kCurrentProcess;
-
- Result = ::GetProcessInformation(&PSN, &infoRec);
- }
- else
- //
- // If no CFM installed, assume it must be a 68K app.
- //
- Result = -1;
-
- if (Result == noErr)
- {
- //
- // Now that we know the app name and FSSpec, we can call GetDiskFragment
- // to get a connID to use in a subsequent call to FindSymbol (it will also
- // return the address of “main” in app, which we ignore). If GetDiskFragment
- // returns an error, we assume the app must be 68K.
- //
- Ptr mainAddr;
- Result = ::GetDiskFragment(infoRec.processAppSpec, 0L, 0L, infoRec.processName,
- kLoadCFrag, &connID, (Ptr*)&mainAddr, errName);
- }
-
- if (Result == noErr)
- {
- //
- // The app is a PPC code fragment, so call FindSymbol
- // to get the exported “qd” symbol so we can access its
- // QuickDraw globals.
- //
- CFragSymbolClass SymClass;
- Result = ::FindSymbol(connID, "\pqd", (Ptr*)&QDGlobals, &SymClass);
- }
- else
- //
- // The app is 68K, so use its A5 to compute the address
- // of its QuickDraw globals.
- //
- QDGlobals = QDGlobalsPtr(*((long*)SetCurrentA5()) - (sizeof(QDGlobals) - sizeof(GrafPtr)));
-
- return QDGlobals;
- }
-
-
-